package com.example.financechain.service.Impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.financechain.Utils.CaptchaUtil;
import com.example.financechain.Utils.JWTUtils;
import com.example.financechain.Utils.JsonData;
import com.example.financechain.Utils.UUIDUtils;
import com.example.financechain.domain.LoginParam;
import com.example.financechain.domain.entity.Role;
import com.example.financechain.mapper.RoleMapper;
import com.example.financechain.service.IRoleService;
import com.example.financechain.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

//    @Autowired
//    private UUIDUtil uuidUtil;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private CaptchaUtil captchaUtil;
    //从SpringBoot的配置文件中取出过期时间

    @Autowired
    IRoleService roleService;



    private Integer timeout = 10;
    //UUID为key, 验证码为Value放在Redis中


    /**
     * 登录校验
     * @param loginParam
     * @return
     */
    @Override
    public JsonData login(LoginParam loginParam) throws NoSuchAlgorithmException {
        if (!versifyCaptcha(loginParam.getToken(),loginParam.getCode())){
            return JsonData.buildError("验证码错误");
        }

        QueryWrapper<Role> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("nick_name",loginParam.getNickname());

        Role role = roleService.getOne(queryWrapper);

        if (role==null){
            return JsonData.buildError("账号不存在");
        }


        if(!addMD5(loginParam.getPassword()).equals(role.getPassword())){
            return JsonData.buildError("密码错误");
        }

        String token = JWTUtils.createToken(role.getRoleId());

        stringRedisTemplate.opsForValue().set(role.getRoleId().toString(), JSON.toJSONString(role));

        return JsonData.buildSuccess("登录成功",token);

    }


    /**
     * 生成验证码
     * @param captcha
     * @return
     */
    public Map<String, Object> createToken(String captcha) {
        //生成一个token
//        String key = uuidUtil.getUUID32();
        String key = UUIDUtils.getUUID(32);
        //生成验证码对应的token  以token为key  验证码为value存在redis中
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, captcha);
        //设置验证码过期时间
        redisTemplate.expire(key, timeout, TimeUnit.MINUTES);
        Map<String, Object> map = new HashMap<>();
        map.put("token", key);
        map.put("expire", timeout);
        return map;
    }
    //生成captcha验证码
    @Override
    public Map<String, Object> captchaCreator() throws IOException {
        Map<String,Object> Info = captchaUtil.catchaImgCreator();
        Map<String, Object> token = createToken(Info.get("text").toString());
        token.put("imgcaptcha", Info.get("encoder"));
        return token;
//        return captchaUtil.catchaImgCreator();
    }


    //验证输入的验证码是否正确
    public boolean versifyCaptcha(String token, String inputCode) {
        //根据前端传回的token在redis中找对应的value
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        if (redisTemplate.hasKey(token)) {
            //验证通过, 删除对应的key
            if (valueOperations.get(token).equals(inputCode)) {
                redisTemplate.delete(token);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    private String  addMD5(String password) throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("MD5");

        // Add original string bytes to digest
        md.update(password.getBytes());

        // Get the hash's bytes
        byte[] bytes = md.digest();

        // Convert the bytes to a hexadecimal format
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }

        return sb.toString();

    }
}
